<!--
 * @Author: 东
 * @Date: 2020-07-28 08:53:38
 * @LastEditTime: 2020-09-12 08:53:56
 * @LastEditors: Please set LastEditors
 * @Description: In User Settings Edit
 * @FilePath: \vue-aliplayer\example\flv.vue
-->
<template>
  <div id="ruien-video-player"
       class="ruien-video-player"
       ref="ruienVideoPlayer"
       :style="fixedStyle">
    <div class="video-list"
         @mousemove.capture="showControls"
         @mouseout.capture="hideControls">
      <div class="main-container"
           :style="`background-color:${bgColor}`">
        <video :id="videoId"
               :ref="videoId"
               class="centeredVideo"
               width="100%"
               height="100%"
               @waiting="onWaiting"
               @canplay="onCanplay"
               @canplaythrough="onCanplay"
               @play="videoPlay"
               @pause="videoPause"
               @ended="videoEnded"
               controls
               :muted="isMuted? false:true">
          Your browser is too old which doesn't support HTML5 video.
        </video>
        <!-- 视频画布 -->
        <div class="video-canvas-box">
          <canvas id="videoCanvas"
                  :width="videoCanvasWidth"
                  :height="videoCanvasHeight"
                  :ref="videoCanvasId"></canvas>
        </div>
        <div class="video-msg"
             :style="`bottom:${videoMsgBottom}px`">
          <div v-for="(item,index) of videoErrorMsgList"
               :key="index"
               class="video-msg-item">{{item}}</div>
        </div>
        <!-- 视频控件 -->
        <transition name="fade">
          <div class="controls"
               v-show="show">
            <div class="controls-btn">
              <div class="controls-btn-left">
                <div v-if="!isLive"
                     :class="['iconfont', isStop? 'icon-play':'icon-stop']"
                     @click="setPlayStatus">
                  <span style="font-size:14px">
                    {{formatDate(nowTime)}} / {{formatDate(totalTime)}}
                  </span>
                </div>
                <span v-else
                      class="live">LIVE</span>
              </div>
              <div class="controls-btn-right">
                <div class="select-box">
                  <!-- <div class="select-value">{{playbackRate}}倍速</div> -->
                  <select @change.stop="changePlaybackRate">
                    <option value="1"
                            :selected='playbackRate === "1"'>1倍速</option>
                    <option value="2"
                            :selected='playbackRate === "2"'>2倍速</option>
                    <option value="4"
                            :selected='playbackRate === "4"'>4倍速</option>
                  </select>
                </div>
                <div class="iconfont icon-pic"
                     @click="screenshot"></div>
                <div :class="['iconfont', isMuted? 'icon-sound':'icon-mute']"
                     @click="setSound"></div>
                <div class="iconfont icon-full"
                     @click="fullscreenHandle"></div>
              </div>
            </div>
            <div>
              <progress-bar :totalTime.sync='totalTime'
                            :bufferLength.sync="bufferLength"
                            :nowTime.sync="nowTime"
                            :isUpdate.sync="updateBar"
                            :videoTime.sync='videoTime'
                            :list='videoKeyList'
                            :totalVideoNum.sync='totalVideoNum'
                            @pauseVideo="videoRef.pause()"
                            @playVideo='setCurrentTime' />
            </div>
          </div>
        </transition>
        <!-- 截图用的画布以及a标签 -->
        <div style="display:none">
          <canvas :id="canvasId"></canvas>
          <a href=""
             :id="downloadId"></a>
        </div>
        <!-- loading -->
        <div class="loading"
             v-show="isLoading">
          <svg-icon icon-class="oval"></svg-icon>
        </div>
      </div>
      <!-- 幕布 -->
      <div class="black-shell"
           :style="`background-color:${bgColor}`"
           v-if="isBlackShow">
        <div class="iconfont icon-no-signal"></div>
        <div style="margin-top:15px">暂无信号</div>
      </div>
    </div>
    <template v-if="videoTest">
      <video-test :activeIndex="activeIndex"
                  :testVideo="testVideo" />
    </template>
  </div>
</template>

<script>
/* eslint-disable */
import axios from 'axios'
import '@/assets/icon-font/iconfont.css'
import progressBar from './component/progress-bar';
import videoTest from './component/video-test'
import screenfull from 'screenfull'
import { http, clearWaitList, pauseRequest, setCancelItems, recoveryRequest } from './request';
const CancelToken = axios.CancelToken
let source = ''
const elementResizeDetectorMaker = require("element-resize-detector")
export default {
  name: 'ruienVideoPlay',
  components: {},
  props: {
    // 视频的url列表
    api: {
      type: String,
      default: ''
    },
    cameraId: {
      type: [String, Number],
      default: ''
    },
    urls: {
      type: Object,
      default: () => { },
    },
    // 需要重新请求后台的方法
    reboot: {
      type: Function,
      default: () => {
        return (() => { })()
      }
    },
    // 单个视频的时长
    videoTime: {
      type: Number,
      default: 60
    },
    // 从第二个视频开始快进的秒数
    fastForwardSec: {
      type: Number,
      default: 0
    },
    bgColor: {
      type: String,
      default: '#000'
    },
    isLive: {
      type: Boolean,
      default: false
    }
  },
  data () {
    return {
      videoId: '',
      canvasId: '',
      downloadId: '',
      videoCanvasId: '',
      show: true,
      isLoading: true,
      isMuted: false,
      isStop: true,
      isBlackShow: true,
      // 总时长
      totalTime: 3600,
      // 视频总数
      totalVideoNum: 1,
      // 播放条更新状态
      updateBar: false,
      // 当前播放时间
      nowTime: 0,
      // 是否手动点击播放
      manualPlayStatus: false,
      // 旧视频列表
      oldVideoList: {},
      // 视频列表
      videoList: {},
      // 视频key列表
      videoKeyList: [],
      // 是否需要重新请求后台视频中
      isRequest: false,
      // 缓存视频列表
      videoBufferList: {},
      // 是否跳跃进度条
      isJump: false,
      // 重载次数
      overloadNum: 0,
      overloadTimer: 0,
      // 错误信息
      videoErrorMsgList: [],
      testVideo: [],
      videoMsgBottom: 0,
      isOne: false,
      currentTime: 0,
      loadingTimer: 0,
      videoCanvasWidth: '',
      videoCanvasHeight: '200',
      controlsTimer: '',
      videoCanvasRef: {},
      ruienVideoPlayerRef: '',
      videoRef: '',
      canvasRef: '',
      timer: '',
      cacheTimer: '',
      timeout: '',
      bufferLength: 0,
      activeIndex: 1,
      playbackRate: 1,
      ctx: '',
      fixedStyle: {
        'position': 'relative',
        'z-index': 0
      }
    }
  },
  mounted () {
    window.$getVideoBufferList = this.getVideoBufferList
    window.$setSource = this.setSource

    const temp = JSON.parse(JSON.stringify(this.urls))

    this.totalVideoNum = this.totalTime / this.videoTime
    this.videoList = Object.assign({}, this.videoList, temp)
    this.videoCanvasId = `videoCanvasId-${this.uuid()}`
    this.canvasId = `canvas-${this.uuid()}`
    this.videoId = `video-${this.uuid()}`
    this.downloadId = `download-${this.uuid()}`

    window.addEventListener('resize', this.monitorFullScreen)
    this.$nextTick(() => {
      this.init()
    })
  },
  beforeDestroy () {
    clearTimeout(this.loadingTimer)
    clearTimeout(this.controlsTimer)
    clearTimeout(this.timeout)
    if (source !== '') {
      clearWaitList(source)
    }
    window.removeEventListener('resize', this.monitorFullScreen)
    this.clearVideoBufferList()
  },
  components: {
    screenfull,
    progressBar,
    videoTest
  },
  computed: {
    videoTest () {
      return window.$videoTest
    }
  },
  watch: {
    show (val) {
      this.videoMsgBottom = val ? 60 : 0
    },
    urls: {
      handler (newVal) {
        const obj = JSON.parse(JSON.stringify(newVal)) || {}

        if (!Object.keys(obj).length) {
          this.clearVideoBufferList()
        }

        this.videoList = Object.assign({}, this.videoList, obj)
        let tempArr = Object.entries(newVal)
        tempArr.sort((a, b) => a[0] - b[0])

        if (window.$videoTest) {
          this.testVideo = []
          for (let index = 0; index < this.totalVideoNum; index++) {
            const element = newVal[index] || '';
            this.testVideo.push(element)
          }
        }

        if (this.videoRef !== '' && !tempArr.length) {
          if (this.isOne) {
            this.isOne = false
            clearWaitList(source)
          }
          this.setSource()
          this.initParam()
        }

        if (!obj['0'] && tempArr.length) {
          this.isBlackShow = false
        }


        if (this.videoRef !== '' && !this.isOne && tempArr.length) {
          // 找出第一个播放的视频地址
          for (let index = 0; index < tempArr.length; index++) {
            const element = tempArr[index];
            if (element) {
              this.isOne = true
              this.isBlackShow = false
              // this.nowTime = index * this.videoTime
              // 添加第一个视频播放地址
              this.initVideo(this.processVideoUrl(element[1]))
              // 更新播放时间
              this.videoRef.currentTime = index * this.videoTime
              break
            }
          }
        }

        // 拉动进度条时后台返回的视频
        if (this.isRequest && obj[this.activeIndex]) {
          this.isRequest = false
          this.initVideo(this.processVideoUrl(obj[this.activeIndex]))
          this.activeIndex++
        }

        // 将新的视频链接转为blob链接
        this.$nextTick(() => {
          tempArr.map(item => {
            if (!this.oldVideoList[item[0]]) {
              this.getVideoBufferList(item[0], this.processVideoUrl(item[1]))
            }
          })

          this.oldVideoList = Object.assign({}, this.oldVideoList, obj)
        })
      },
      immediate: true,
      deep: true
    }
  },
  methods: {
    // 初始化
    init () {
      const videoRef = this.$refs[this.videoId]
      const canvasRef = this.$refs[this.canvasId]
      const videoCanvasRef = this.$refs[this.videoCanvasId]
      const erd = elementResizeDetectorMaker();
      const self = this

      this.canvasRef = canvasRef
      this.videoRef = videoRef
      this.videoCanvasRef = videoCanvasRef
      this.ruienVideoPlayerRef = this.$refs.ruienVideoPlayer

      this.videoErrorMMsg(videoRef)

      let element = document.querySelector('.ruien-video-player')
      this.ctx = videoCanvasRef.getContext('2d')
      videoRef.addEventListener('progress', this.getBufferTime)
      erd.listenTo(this.$refs.ruienVideoPlayer, function (element) {
        // 播放器宽度发生变化时更新画布和播放条的大小
        self.setVideoCanvasSize()
        self.updateBar = !self.updateBar
      });
      this.initParam()
    },
    // TODO: 初始化参数
    initParam () {
      this.bufferLength = 0
      this.activeIndex = 1
      this.playbackRate = 1
      this.currentTime = 0
      this.loadingTimer = 0
      this.nowTime = 0
      this.isOne = false
      this.isBlackShow = true
      this.oldVideoList = Object.assign({}, {}, {})
      this.videoBufferList = Object.assign({}, {}, {})
      this.videoRef.src = ''
      this.videoKeyList = []
      this.setVideoCanvasSize()
    },
    //TODO 初始化视频
    initVideo (url) {
      this.videoRef.src = url
      this.videoRef.load()
      this.videoRef.addEventListener('loadeddata', this.loadeddata)
    },
    // 设置source
    setSource () {
      source = CancelToken.source()
    },
    // 处理videoUrl返回
    processVideoUrl (url) {
      const keys = url.split('/')
      if (keys.length > 3) {
        const key = keys.splice(1, 1)
        return `${this.api}/${key[0]}/${this.cameraId}${keys.join('/')}`
      } else {
        return `${this.api}/${this.cameraId}${url}`
      }
    },
    // 清除缓冲数据
    clearVideoBufferList () {
      this.videoList = {}
      const list = Object.values(this.videoBufferList)
      list.map(item => {
        URL.revokeObjectURL(item)
      })
    },
    // 视频错误信息
    videoErrorMMsg (videoRef) {
      const self = this
      videoRef.onerror = function () {
        const index = self.activeIndex - 1
        if (self.overloadNum >= 5) {
          self.videoErrorMsgList.push(`加载次数过多，错误编号:${index}，请重新刷新页面后再尝试`)
        }

        if (self.isOne && self.overloadNum < 5) {
          if (self.overloadNum < 1) {
            self.videoErrorMsgList.push('视频资源请求失败,5秒后重新加载')
          }
          clearTimeout(self.overloadTimer)
          self.overloadTimer = setTimeout(() => {
            if (self.overloadNum < 5) {
              self.videoErrorMsgList.push(`加载视频${self.overloadNum + 1}次`)
              const tempUrl = self.videoList[index] ? self.processVideoUrl(self.videoList[index]) : self.videoList[index]
              const url = self.videoBufferList[index] || tempUrl
              self.initVideo(url)
            }
            self.overloadNum++
          }, 5000);
        }
      }
    },
    //TODO 设置视频画布的大小
    setVideoCanvasSize () {
      this.$nextTick(() => {
        const videoBox = this.ruienVideoPlayerRef
        const width = videoBox.clientWidth
        const height = videoBox.clientHeight
        this.videoCanvasWidth = width
        this.videoCanvasHeight = width * 0.5625 // 16:9
      })
    },
    //TODO 生成uuid
    uuid () {
      let s = [];
      let hexDigits = '0123456789abcdef';
      for (let i = 0; i < 36; i++) {
        s[i] = hexDigits.substr(Math.floor(Math.random() * 0x10), 1);
      }
      s[14] = '4';
      s[19] = hexDigits.substr((s[19] & 0x3) | 0x8, 1);
      s[8] = s[13] = s[18] = s[23] = '-';

      let uuid = s.join('');
      return uuid;
    },
    //TODO 跳转到进度条当前播放时间
    setCurrentTime (val) {
      this.isJump = true
      this.currentTime = val.s

      // 当进度条移动到尾端
      if (val.m === this.totalVideoNum.length) {
        this.currentTime = 10
        this.activeIndex = this.totalVideoNum - 1
        return false
      }

      if (val.m > 0) {
        this.activeIndex = val.m
      } else {
        this.activeIndex = 0
      }

      this.nowTime = val.totalSeconds

      this.videoEnded()
    },
    //TODO 获取到视频第一帧
    loadeddata () {
      recoveryRequest()
      if (this.manualPlayStatus) {
        clearTimeout(this.loadingTimer)
        this.videoErrorMsgList = []
        this.overloadNum = 0
        this.isLoading = false
        this.manualPlayStatus = false
        this.videoRef.play()
        this.videoRef.playbackRate = this.playbackRate
        this.isStop = false
        if (this.activeIndex !== 1 && !this.currentTime) {
          this.videoRef.currentTime = this.fastForwardSec
        } else {
          this.videoRef.currentTime = this.currentTime
        }
        this.currentTime = 0
      }
    },
    //TODO 播放状态
    setPlaySatus () {
      clearTimeout(this.timeout)
      const currentTime = this.videoRef.currentTime + ((this.activeIndex - 1) * this.videoTime)
      this.ctx.drawImage(this.videoRef, 0, 0, this.videoCanvasWidth, this.videoCanvasHeight)
      this.nowTime = currentTime

      this.timeout = setTimeout(() => {
        this.timer = requestAnimationFrame(this.setPlaySatus)
      }, 100);
    },
    //TODO 开始播放
    videoPlay () {
      this.videoRef.removeEventListener('loadeddata', this.loadeddata)
      this.manualPlayStatus = true
      this.setPlaySatus()
    },
    //TODO 暂停播放
    videoPause () {
      cancelAnimationFrame(this.timer)
      this.isStop = true
      return Promise.resolve()
    },
    //TODO 播放结束
    videoEnded () {
      cancelAnimationFrame(this.timer)
      if (this.totalVideoNum > this.activeIndex) {
        const tempUrl = this.videoList[this.activeIndex] ? this.processVideoUrl(this.videoList[this.activeIndex]) : this.videoList[this.activeIndex]

        const url = this.videoBufferList[this.activeIndex] || tempUrl

        clearTimeout(this.loadingTimer)
        this.videoRef.pause()
        this.loadingTimer = setTimeout(() => {
          this.isLoading = true
        }, 300);

        // 在已有的视频列表中和缓存列表中没有找到可用的url,请求后台加载对应的视频
        if (!url) {
          this.isRequest = true
          this.updateBar = this.updateBar
          this.reboot(this.activeIndex)
          return
        }

        pauseRequest(source)

        if (this.isJump) {
          this.isJump = false
          this.updateBar = this.updateBar
          this.reboot(this.activeIndex)
        }

        this.$nextTick(() => {
          this.initVideo(url)
        })

      } else {
        // 当视频播放到最后时想进行重播时跳回到第一个视频地址
        this.isStop = true
        this.manualPlayStatus = false
        this.activeIndex = 0
        this.initVideo(this.videoBufferList[0])
      }
      this.activeIndex++
    },
    //TODO 倍速设置
    changePlaybackRate (val) {
      this.playbackRate = val.target.value
      this.videoRef.playbackRate = parseFloat(val.target.value)
    },
    //TODO url 转 blob连接
    async getBlobUrl ({ url, key = -1 } = {}) {
      const params = key === -1 ? {} : { key }
      const res = await http({
        method: 'get',
        url: url,
        responseType: 'blob',
        params: params,
        cancelToken: source.token
      }).catch(function (error) {
        if (error.code == -2) { // 暂停请求
          return { data: -2 }
        }
        if (error.code) { return }
      })
      return res || { data: -1 }
    },
    //TODO 获取缓冲的时间
    getBufferTime () {
      if (!this.isRequest && this.videoRef.readyState === 4) {
        this.isLoading = false
      }
      // this.isLoading = false
      let duration = this.videoRef.duration; // 当前视频总长度
      let bufferedTime = 0
      if (duration > 0) {
        for (var i = 0; i < this.videoRef.buffered.length; i++) {
          // 寻找当前时间之后最近的点
          if (this.videoRef.buffered.start(this.videoRef.buffered.length - 1 - i) <= this.videoRef.currentTime) {
            // 获取到单个视频的缓冲时间
            let bufferLength = (this.videoRef.buffered.end(this.videoRef.buffered.length - 1 - i))
            // 总缓冲条 = 当前获取的缓冲时间 *（当前播放的视频下标 - 1） * 单个视频的长度
            bufferedTime = bufferLength + ((this.activeIndex - 1) * this.videoTime)
            break;
          }
        }
      }

      // 如果在缓存列表中有该视频的链接，这总缓冲条等于当前下标连号的最大值 * 单个视频长度
      if (this.videoBufferList[this.activeIndex]) {
        let num = this.activeIndex
        for (let index = this.activeIndex; index < this.totalVideoNum; index++) {
          if (!this.videoBufferList[index]) { break }
          num++
        }
        this.bufferLength = num * this.videoTime
      } else {
        this.bufferLength = bufferedTime
      }
    },
    //TODO 缓存视频文件
    getVideoBufferList (key, url) {
      this.getBlobUrl({ url, key }).then(res => {
        if (res.data === -1) { return }

        // 暂停请求后将取消请求的视频key和url提取出来
        if (res.data === -2) {
          setCancelItems({ url, key })
          return
        }

        this.videoBufferList[key] = URL.createObjectURL(res.data)
        this.videoKeyList.push(key)
        this.getBufferTime()
      })
    },
    //TODO 显示控件
    showControls () {
      clearTimeout(this.controlsTimer)
      if (!this.show) {
        this.updateBar = !this.updateBar
      }
      this.show = true
    },
    //TODO 隐藏控件
    hideControls () {
      clearTimeout(this.controlsTimer)
      this.controlsTimer = setTimeout(() => {
        this.show = false
      }, 300)
    },
    //TODO 设置开关声音
    setSound () {
      this.isMuted = !this.isMuted
    },
    //TODO 设置关闭/开启播放
    setPlayStatus () {
      if (this.isLive) { return }
      if (this.videoRef === null) { return }
      if (this.videoRef === undefined) { return }
      if (this.isRequest) { return }
      this.isStop = !this.isStop
      if (this.isStop) {
        this.videoRef.pause()
      } else {
        this.videoRef.play()
      }
    },
    //TODO 截图
    screenshot () {
      this.$nextTick(() => {
        const video = document.getElementById(this.videoId);
        const canvas = document.getElementById(this.canvasId);
        const download = document.getElementById(this.downloadId);
        const width = video.videoWidth
        const height = video.videoHeight
        canvas.width = width
        canvas.height = height
        let ctx = canvas.getContext('2d');
        ctx.drawImage(video, 0, 0, width, height);
        const png = canvas.toDataURL("image/png")
        this.getBlobUrl({ url: png }).then(res => {
          if (res.data === -1) {
            alert('图片转换失败')
            return false
          }
          const url = URL.createObjectURL(res.data)
          download.setAttribute('href', url)
          download.download = this.getNewDate()
          download.click()
          URL.revokeObjectURL(url)
        })
      })
    },
    //TODO 获取当前时间
    getNewDate () {
      const date = new Date()
      const year = date.getFullYear()
      const month = date.getMonth() + 1
      const day = date.getDate()
      const h = date.getHours() > 9 ? date.getHours() : `0${date.getHours()}`
      const m = date.getMinutes() > 9 ? date.getMinutes() : `0${date.getMinutes()}`
      const s = date.getSeconds() > 9 ? date.getSeconds() : `0${date.getSeconds()}`

      return `${year}年${month}月${day}日 ${h}:${m}:${s}`
    },
    //TODO 格式化时间
    formatDate (sec) {
      if (sec < 0) {
        return '00:00'
      }
      const h_ = Math.floor(sec / 3600)
      const m_ = Math.floor(sec / 60)
      const s_ = sec % 60
      const h = h_ > 9 ? h_.toFixed() : `0${h_.toFixed()}`
      const m = m_ > 9 ? m_.toFixed() : `0${m_.toFixed()}`
      const s = s_ > 9 ? s_.toFixed() : `0${s_.toFixed()}`

      if (h > 0) {
        return `${h}:${m >= 60 ? '00' : m}:${s >= 60 ? '00' : s}`
      }
      return `${m >= 60 ? '00' : m}:${s >= 60 ? '00' : s}`
    },
    //TODO 全屏
    fullscreenHandle () {
      if (!screenfull.isFullscreen) {
        screenfull.toggle().then(() => {
          this.fixedStyle = {
            'position': 'fixed',
            'z-index': 99999999
          }

          this.setVideoCanvasSize()
          this.updateBar = !this.updateBar
        })
      } else {
        screenfull.exit().then(() => {
          this.fixedStyle = {
            'position': 'relative',
            'z-index': 0
          }

          this.setVideoCanvasSize()
          this.updateBar = !this.updateBar
        })
      }
    },
    //TODO 关闭全屏
    beforeClose () {
      this.setVideoCanvasSize()
      this.updateBar = !this.updateBar
      this.fixedStyle = {
        position: 'relative'
      }
      if (screenfull.isFullscreen) {
        screenfull.exit()
      }
    },
    //TODO 监听是否为全屏状态
    monitorFullScreen () {
      if (screenfull.isEnabled) {
        screenfull.on('change', () => {
          if (!screenfull.isFullscreen) {
            this.beforeClose()
          }
        })
      }
    },
    //TODO 当前视频卡顿缓冲完成
    onCanplay (event) {
      clearTimeout(this.loadingTimer)
      this.getBufferTime()

      if (this.manualPlayStatus) {
        this.manualPlayStatus = false
        this.videoPlay()
      }

      if (!this.isRequest) {
        this.isLoading = false
      }
    },
    //TODO 当前视频卡顿视频缓冲
    onWaiting (event) {
      cancelAnimationFrame(this.timer)
      clearTimeout(this.loadingTimer)
      this.loadingTimer = setTimeout(() => {
        this.isLoading = true
      }, 300);
    }
  }
}
</script>

<style lang='scss' scoped>
.black-shell {
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  position: absolute;
  width: 100%;
  height: 100%;
  z-index: 9999999;
  background-color: black;
  color: white;
}
.list-item {
  display: inline-block;
  margin-right: 10px;
}

.list-enter-active,
.list-leave-active {
  transition: all 1s;
}

.list-enter,
.list-leave-to {
  opacity: 0;
  transform: translateX(30px);
}

.list-move {
  transition: transform 0.5s;
}

.video-canvas-box {
  position: absolute;
  width: 100%;
  height: 100%;
  display: flex;
  justify-content: center;
  align-items: center;
}

.ruien-video-player {
  font-family: "Avenir", Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #000000;
  width: 100%;
  height: 100%;
  position: relative;
  top: 0;
  left: 0;
}

.msg-list {
  position: absolute;
  width: 100%;
  bottom: 0;
  left: 0;
  padding: 10px;
  box-sizing: border-box;
  text-align: left;
  z-index: 1;
}

.msg-list .msg-item {
  padding: 5px;
  box-sizing: border-box;
  border-radius: 4px;
  background-color: rgb(44, 117, 189);
  color: white;
  display: inline-block;
  font-size: 12px;
  margin-top: 8px;
}

.curtain {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background: #000000;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  z-index: 1;
}

.loading {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  display: flex;
  justify-content: center;
  align-items: center;
}

.curtain > div {
  display: flex;
  justify-content: center;
  align-items: center;
  color: white;
  margin-bottom: 10px;
}

.fade-enter-active,
.fade-leave-active {
  transition: opacity 0.5s;
}
.fade-enter, .fade-leave-to /* .fade-leave-active below version 2.1.8 */ {
  opacity: 0;
}

.main-container {
  display: block;
  flex: 1;
  width: 100%;
  margin-left: auto;
  margin-right: auto;
  background-color: #000000;
  position: relative;
  .video-msg {
    color: white;
    position: absolute;
    bottom: 0;
    left: 0;
    margin-left: 5px;
    display: inline-block;
    text-align: left;
    .video-msg-item {
      padding: 3px 5px;
      margin-bottom: 10px;
      border-radius: 4px;
      background-color: #676767;
    }
  }
}

//视频
.centeredVideo {
  display: none;
  width: 100%;
  height: 100%;
  margin-left: auto;
  margin-right: auto;
  margin-bottom: auto;
  position: absolute;
  left: 106%;
}

.controls {
  position: absolute;
  bottom: 0;
  left: 0;
  width: 100%;
  height: 60px;
  background-color: rgba(19, 19, 19, 0.6);
  color: white;
  background: linear-gradient(to top, #050505, transparent);
  text-align: left;
  margin-left: auto;
  margin-right: auto;
  z-index: 2;
}
.controls .controls-btn {
  width: 100%;
  height: 30px;
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.controls-btn .controls-btn-left {
  flex: 6;
  display: flex;
  justify-content: flex-start;
  align-items: center;
  padding: 10px;
  box-sizing: border-box;
}

.controls-btn .controls-btn-right {
  flex: 5;
  display: flex;
  justify-content: flex-end;
  align-items: center;
  padding: 10px;
  box-sizing: border-box;
}

.live {
  margin-right: 16px;
}

.select-box > select {
  position: relative;
  border: none;
  color: white;
  background-color: #3e3e3e;
  padding: 3px 4px;
  border-radius: 4px;
}

.controls-btn .controls-btn-left > div,
.controls-btn .controls-btn-right > div {
  margin-right: 16px;
  cursor: pointer;
}

.video-list {
  display: flex;
  width: 100%;
  height: 100%;
  position: relative;
}
</style>